//
//  WJSimpleNetwork.m
//  boss
//
//  Created by 王军 on 16/10/9.
//  Copyright © 2016年 王军. All rights reserved.
//
/***
 简单的网络访问，系统原生。
 需求：传入url，地址，参数，返回结果。
 需要保持cookie会话。
 需要https
 ***/

#import "WJSimpleNetwork.h"
#import "NSDictionary+MutableDeepCopy.h"

#define USERAGENT @"App/1.0"

@implementation WJSimpleNetwork

+(void)getMethod:(NSURL *)url format:(NSString *)format success:(void (^)(id result))success fail:(void(^)(NSString *)) fail{
    if (url == nil) {
        NSLog(@"invalid url");
        return;
    }
    NSMutableDictionary *headers = [[NSMutableDictionary alloc]init];
    [headers setObject:@"application/json" forKey:@"accept"];
    [headers setObject:@"application/json" forKey:@"Content-Type"];
    NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
    [mRequest setValue:USERAGENT forHTTPHeaderField:@"User-Agent"];
    if (mRequest == nil) {
        NSLog(@"invalid mRequest");
        return;
    }
    [mRequest setHTTPMethod:@"GET"];
    [mRequest setAllHTTPHeaderFields:headers];
    [mRequest setHTTPShouldHandleCookies:YES];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:[WJSimpleNetwork shareInstance] delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionDataTask *_dataTask = [session dataTaskWithRequest:mRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            if (fail) {
                fail(@"网络错误");
            }
            return;
        }
        if ([format.uppercaseString isEqualToString:@"JSON"]) {
            NSError *jsonErr = nil;
            NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonErr];
            if (jsonErr) {
                NSString *aString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                NSString *retStr = [NSString stringWithFormat:@"jsonErr error = %@",aString];
                NSLog(@"%@",retStr);
                if (fail) {
                    fail(@"返回数据格式不对");
                }
            } else {
                if (jsonDict ==nil || [jsonDict isKindOfClass:[NSNull class]]) {
                    if (fail) {
                        fail(@"网络错误");
                    }
                    return;
                }
                if (![jsonDict isKindOfClass:[NSDictionary class]]) {
                    if (fail) {
                        fail(@"网络错误");
                    }
                    return;
                }
                if (success) {
                    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
                    NSInteger responseStatusCode = [httpResponse statusCode];
                    NSMutableDictionary *retDic = [jsonDict mutableDeepCopy];
                    retDic[@"httpCode"] = [NSString stringWithFormat:@"%ld", responseStatusCode];
                    success(retDic);
                }
            }
        }
        else {
            NSString *aString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            if (success) {
                success(aString);
            }
        }
    }];
    [_dataTask resume];
}

+(void)getMethodContent:(NSURL *)url success:(void(^)(NSString *))success fail:(void(^)(NSString *)) fail{
    [WJSimpleNetwork getMethod:url format:@"STRING" success:^(id result) {
        success(result);
    } fail:^(NSString * message) {
        fail(message);
    }];
}

+(void)getMethodJson:(NSURL *)url success:(void(^)(NSMutableDictionary *))success fail:(void(^)(NSString *)) fail{
    [WJSimpleNetwork getMethod:url format:@"JSON" success:^(id result) {
        success(result);
    } fail:^(NSString * message) {
        fail(message);
    }];
}

+(void)postParameters:(NSMutableDictionary *)params WithUrl:(NSURL *)url setRequest:(void(^)(NSMutableDictionary *))setRequest success:(void(^)(NSDictionary *))success fail:(void(^)(NSString *)) fail{
    [self request:@"POST" params:params WithUrl:url setRequest:setRequest success:success fail:fail];
}


/**
 *  post网络访问
 */
+(void)postParameters:(NSMutableDictionary *)params WithUrl:(NSURL *)url success:(void(^)(NSDictionary *))success fail:(void(^)(NSString *)) fail{
    [WJSimpleNetwork postParameters:params WithUrl:url setRequest:nil success:success fail:fail];
}

/**
 *  post网络访问
 */
+(void)postParameters:(NSMutableDictionary *)params WithUrlStr:(NSString *)urlStr  success:(void(^)(NSDictionary *))success fail:(void(^)(NSString *)) fail{
    NSURL *url = [NSURL URLWithString:urlStr];
    if ([params isKindOfClass:[NSMutableDictionary class]]) {
        //        [params setObject:@"1" forKey:@"osType"];//1 ios, 2 android //clientID， deviceToken.
    }
    [WJSimpleNetwork postParameters:params WithUrl:url success:[success copy] fail:[fail copy]];
}

/**
 *  上传头像（文件）
 */
#define boundary @"AaB03x"
+(void)uploadImage:(NSMutableDictionary *)params data:(NSData *)imageData WithUrlStr:(NSString *)urlStr  success:(void(^)(NSDictionary *))success fail:(void(^)(NSString *)) fail{
    NSURL *url = [NSURL URLWithString:urlStr];
    if (url == nil) {
        NSLog(@"invalid url");
        return;
    }
    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setTimeoutInterval:120];
    [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; charset=utf-8;boundary=%@", boundary];
    [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
    //---设置cookie
    NSMutableDictionary *headers = [[NSMutableDictionary alloc]init];
    [request setAllHTTPHeaderFields:headers];
    [request setValue:USERAGENT forHTTPHeaderField:@"User-Agent"];
    NSData *bodyData=[self createBodyData:imageData token:params[@"token"]];
    //--------------------------------
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&error];
    if (error) {
        NSLog(@"error = %@",error);
        return;
    }
    [request setHTTPBody:jsonData];
    //--------------------------------
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:[WJSimpleNetwork shareInstance] delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionUploadTask *uploadTask =  [session uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            //             fail(error.description);
            fail(@"网络错误");
            return;
        }else{
            
            if([response isKindOfClass:[NSURLResponse class]]){
                NSHTTPURLResponse *httpResponse  = (NSHTTPURLResponse *)response;
                NSLog(@"%@",httpResponse);
            }
        }
        NSError *jsonErr = nil;
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonErr];
        if (jsonErr) {
            NSLog(@"jsonErr error = %@",error);
            return;
        }else{
            NSString *msg = jsonDict[@"message"];
            if (msg != nil) {
                NSLog(@"message=%@",msg);
            }
            NSString *code = [self obj2str:jsonDict[@"code"]] ;
            if (code != nil && [@"-2" isEqualToString:code])
            {
                fail(@"请重新登录");
                return;
            }
            NSString *message = [self obj2str:jsonDict[@"message"]] ;
            if (message != nil && [@"token错误" isEqualToString:message])
            {
                fail(@"请重新登录");
                return;
            }
            NSString *error = [self obj2str:jsonDict[@"error"]] ;
            if (error != nil && [@"0" isEqualToString:error]) {
                fail(@"请重新登录");
                return;
            }
            success(jsonDict);
        }
    }];
    [uploadTask resume];
}

/** 构建数据包，表单提交图片 */
+(NSData *)createBodyData:(NSData *)fileData token:(NSString *)token{
    NSMutableString *bodyString = [[NSMutableString alloc] init];
    //2.拼接body string
    //(1)access_token
    //    [bodyString appendFormat:@"--%@\r\n", boundary];
    //    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n"];
    //    [bodyString appendFormat:@"xxxxxx\r\n"];
    
    [bodyString appendFormat:@"--%@\r\n", boundary];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"token\"\r\n\r\n"];
    [bodyString appendFormat:@"%@\r\n",token];
    
    //(2)status
    //    [bodyString appendFormat:@"--%@\r\n", boundary];
    //    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"status\"\r\n\r\n"];
    //    [bodyString appendFormat:@"上传头像\r\n"];
    
    //(3)pic
    [bodyString appendFormat:@"--%@\r\n", boundary];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"file.jpg\"\r\n"];
    [bodyString appendFormat:@"Content-Type:image/jpeg\r\n\r\n"];
    
    //3.string --> data
    NSMutableData *bodyData = [NSMutableData data];
    //拼接的过程
    //前面的bodyString, 其他参数
    [bodyData appendData:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
    //图片数据
    [bodyData appendData:fileData];
    
    //4.结束的分隔线
    NSString *endStr = [NSString stringWithFormat:@"\r\n--%@--\r\n",boundary];
    //拼接到bodyData最后面
    [bodyData appendData:[endStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    return bodyData;
}

/** 对象转换成string */
+(NSString*)obj2str:(id)obj{
    if(nil==obj ||obj == NULL){
        return @"";
    }
    if([obj isKindOfClass:NSClassFromString(@"NSNumber")]){
        return [obj stringValue];
    }else if([obj isKindOfClass:NSClassFromString(@"NSString")]){
        return obj;
    }else if([obj isKindOfClass:NSClassFromString(@"NSNull")]){
        return @"";
    }
    return obj;
}

//通过设置, 使用 UIWebView 的 loadRequest 方法load NSURLRequest 可以共用 Cookie.
+(void)saveCookie{
    NSString *kServerAddress = @"https://xxx.xxxx.cn";
    NSString *kUserDefaultsCookie = @"kUserDefaultsCookie";
    
    //当请求成共后调用如下代码, 保存Cookie
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL: [NSURL URLWithString:kServerAddress]];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:cookies];
    [[NSUserDefaults standardUserDefaults] setObject:data forKey:kUserDefaultsCookie];
}

//通过设置, 使用 UIWebView 的 loadRequest 方法load NSURLRequest 可以共用 Cookie.
+(void)setCookie{
    NSString *kUserDefaultsCookie = @"kUserDefaultsCookie";
    NSData *cookiesdata = [[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultsCookie];
    if([cookiesdata length]) {
        NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];
        NSHTTPCookie *cookie;
        for (cookie in cookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }
    }
}

+(NSArray *)getCookieArray{
    NSString *kUserDefaultsCookie = @"kUserDefaultsCookie";
    NSData *cookiesdata = [[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultsCookie];
    if([cookiesdata length]) {
        NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];
        return cookies;
    }
    return [NSMutableArray new];
}

/**
 *  单例
 *
 *  @return return value
 */
+(WJSimpleNetwork *)shareInstance{
    static WJSimpleNetwork *r_rootInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        r_rootInstance = [[WJSimpleNetwork alloc] init];
    });
    return r_rootInstance;
}

//https 认证
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
    NSString *method = challenge.protectionSpace.authenticationMethod;
    NSLog(@"%@", method);
    if([method isEqualToString:NSURLAuthenticationMethodServerTrust]){
        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
        return;
    }
}

/**
 *  post网络访问
 */
+(void)request:(NSString *)method params:(NSMutableDictionary *)params WithUrl:(NSURL *)url setRequest:(void(^)(NSMutableDictionary *))setRequest success:(void(^)(NSDictionary *))success fail:(void(^)(NSString *)) fail{
    if ([method isEqualToString:@"GET"] || [method isEqualToString:@"get"]) {
        method = @"GET";
    } else if ([method isEqualToString:@"POST"] || [method isEqualToString:@"post"]){
        method = @"POST";
    } else if ([method isEqualToString:@"PUT"] || [method isEqualToString:@"put"]){
        method = @"PUT";
    } else if ([method isEqualToString:@"DELETE"] || [method isEqualToString:@"delete"]){
        method = @"DELETE";
    } else{
        NSLog(@"Warning,method=%@",method);
        method = @"GET";
    }
    if (url == nil) {
        NSLog(@"invalid url");
        return;
    }
    // 设置 headers
    NSMutableDictionary *headers = [[NSMutableDictionary alloc]init];
    [headers setObject:@"application/json" forKey:@"accept"];
    [headers setObject:@"application/json" forKey:@"Content-Type"];
    if (setRequest) {
        setRequest(headers);
    }
    // 初始化请求
    NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
    [mRequest setValue:USERAGENT forHTTPHeaderField:@"User-Agent"];
    if (mRequest == nil) {
        NSLog(@"invalid mRequest");
        return;
    }
    [mRequest setHTTPMethod:method];
    [mRequest setHTTPShouldHandleCookies:YES];
    NSError *error = nil;
    if ([method isEqualToString:@"GET"]) {
        // 参数拼进url
        
        
    }else{
        [mRequest setAllHTTPHeaderFields:headers];
        if (params && [params isKindOfClass:[NSDictionary class]]) {
            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&error];
            if (error) {
                NSLog(@"error = %@",error);
                return;
            }
            [mRequest setHTTPBody:jsonData];
        }
    }
    // ssl 认证
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:[WJSimpleNetwork shareInstance] delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionDataTask *_dataTask = [session dataTaskWithRequest:mRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"网络访问错误 = %@",error);
            if (fail) {
                fail(@"网络错误");
            }
            return;
        }else{
            if([response isKindOfClass:[NSURLResponse class]]){
            }
        }
        NSError *jsonErr = nil;
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonErr];
        if (jsonErr) {
            NSLog(@"jsonErr error = %@",error);
            //把data变成string
            NSString *aString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSString *retStr = [NSString stringWithFormat:@"jsonErr error = %@",aString];
            NSLog(@"%@",retStr);
            if (fail) {
                fail(@"返回数据格式不对");
            }
            return;
        }else{
            if (jsonDict ==nil || [jsonDict isKindOfClass:[NSNull class]]) {
                NSLog(@"网络返回null数据，");
                if (fail) {
                    fail(@"网络错误");
                }
                return;
            }
            if (![jsonDict isKindOfClass:[NSDictionary class]]) {
                if (fail) {
                    fail(@"网络错误");
                }
                return;
            }
            NSString *msg = jsonDict[@"message"];
            if (msg == nil) {
                msg = jsonDict[@"msg"];
            }
            if (msg != nil) {
                NSLog(@"message=%@",msg);
            }
            NSString *error = [self obj2str:jsonDict[@"error"]] ;
            if (error != nil && [@"0" isEqualToString:error]) {
                //                [VeryCloudUtils sendEventNotice:kEvent_USER_LOGOUT_TIMEOUT];//突然超时
                //                [VeryCloudManager loginOut];
                
                if (fail) {
                    fail(@"请重新登录");
                }
                return;
            }
            if (success) {
                NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
                NSInteger responseStatusCode = [httpResponse statusCode];
                NSMutableDictionary *retDic = [jsonDict mutableDeepCopy];
                retDic[@"httpCode"] = [NSString stringWithFormat:@"%ld", responseStatusCode];
                success(retDic);
            }
        }
    }];
    [_dataTask resume];
}

@end

